import React, {
  createContext,
  useCallback,
  useContext,
  useMemo,
  useState,
} from "react";
import {
  getCardList,
  deleteCard,
  addCard,
  updateCard,
} from "../services/index";
import { ITask } from "../types/task";
import moment from "moment";

interface TasksContextData {
  tasks: ITask[];
  loadTasks: () => Promise<void>;
  createTask: (title: string, category: string, date: Date) => Promise<void>;
  updateTask: () => Promise<void>;
  deleteTask: (taskId: number) => Promise<void>;
  selectedTaskId: number | undefined;
  updateSelectedTaskId: (taskId?: number) => void;
  activeDate: string | undefined;
  updateActiveDate: (taskId?: string) => void;
  startDate: string | undefined;
  updateStartDate: (taskId?: string) => void;
  endDate: string | undefined;
  updateEndDate: (taskId?: string) => void;
  selectedMood: number | undefined;
  updateSelectedMood: (taskId?: number) => void;
  selectedTime: string | undefined;
  updateSelectedTime: (taskId?: string) => void;
  quickVisible: boolean;
  updateQuickVisible: (taskId?: boolean) => void;
  createModalVis: boolean;
  updateCreateModalVis: (taskId?: boolean) => void;
}

const TasksContext = createContext({} as TasksContextData);

interface TasksProviderProps {
  children: React.ReactNode;
}

export const TasksProvider: React.FC<TasksProviderProps> = ({ children }) => {
  const [selectedTaskId, setTaskSelectedId] = useState<object | undefined>(
    undefined
  );
  const [createModalVis, setCreateModalVis] = useState(false);
  const [activeDate, setActiveDate] = useState<string | undefined>(
    moment().format("YYYY-MM-DD")
  );

  const [startDate, setStartDate] = useState<string | undefined>(
    moment().format("YYYY-MM-DD")
  );

  const [endDate, setEndDate] = useState<string | undefined>(
    moment().subtract(6, "days").format("YYYY-MM-DD")
  );

  const [selectedMood, setSelectedMood] = useState<string | undefined>(
    undefined
  );
  const [selectedTime, setSelectedTime] = useState<string | undefined>(
    undefined
  );
  const [quickVisible, setQuickVisible] = useState<boolean>(false);
  const [tasks, setTasks] = useState([]);

  async function loadTasks(params) {
    const tasksLoaded = await getCardList(params);
    const datas = tasksLoaded.data.days ? tasksLoaded.data.days.reverse() : [];

    setTasks(datas);
  }

  async function createTask(params) {
    await addCard(params);
  }

  async function updateTask(params) {
    await updateCard(params);
  }

  async function deleteTask(id: number) {
    await deleteCard(id);
  }

  const updateSelectedTaskId = useCallback(
    (taskId?: number) => {
      setTaskSelectedId(taskId);
    },
    [setTaskSelectedId]
  );

  const updateActiveDate = useCallback(
    (taskId?: string) => {
      setActiveDate(taskId);
    },
    [setActiveDate]
  );

  const updateStartDate = useCallback(
    (taskId?: string) => {
      setStartDate(taskId);
    },
    [setStartDate]
  );

  const updateEndDate = useCallback(
    (taskId?: string) => {
      setEndDate(taskId);
    },
    [setEndDate]
  );

  const updateSelectedMood = useCallback(
    (taskId?: string) => {
      setSelectedMood(taskId);
    },
    [setSelectedMood]
  );

  const updateSelectedTime = useCallback(
    (taskId?: string) => {
      setSelectedTime(taskId);
    },
    [setSelectedTime]
  );

  const updateQuickVisible = useCallback(
    (taskId?: boolean) => {
      setQuickVisible(taskId);
    },
    [setQuickVisible]
  );

  const updateCreateModalVis = useCallback(
    (taskId?: boolean) => {
      setCreateModalVis(taskId);
    },
    [setCreateModalVis]
  );

  return (
    <TasksContext.Provider
      value={{
        tasks,
        loadTasks,
        createTask,
        updateTask,
        deleteTask,
        selectedTaskId,
        updateSelectedTaskId,
        activeDate,
        updateActiveDate,
        startDate,
        updateStartDate,
        endDate,
        updateEndDate,
        selectedMood,
        updateSelectedMood,
        selectedTime,
        updateSelectedTime,
        quickVisible,
        updateQuickVisible,
        createModalVis,
        updateCreateModalVis,
      }}
    >
      {children}
    </TasksContext.Provider>
  );
};

export function useTasks() {
  const context = useContext(TasksContext);

  if (!context) throw new Error("useTasks must be used inside a TasksProvider");

  return context;
}
